package com.mytools.common.example.schedule;


import lombok.Data;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.locks.LockSupport;

/**
 * @author LJK
 * @description
 * @date 2025/2/8
 */
public class ScheduleService {
    Tigger tigger = new Tigger();
    ExecutorService executorService = Executors.newFixedThreadPool(6);

    void schedule(Runnable command, Integer delay) {
        Job job = new Job();
        job.setTask(command);
        job.setDelay(delay);
        job.setStartTime(System.currentTimeMillis() + delay);
        tigger.queue.offer(job);
        tigger.wakeUp();
    }

    //这是一个触发器，他只有一个核心功能：在对应的时间将task放入线程池，让线程池执行task
    class Tigger {
        BlockingQueue<Job> queue = new PriorityBlockingQueue<>();
        Thread thread = new Thread(() -> {
            while (true) {
                while (queue.isEmpty()) {
                    LockSupport.park();
                }
                Job laterJob = queue.peek();
                if (laterJob.startTime > System.currentTimeMillis()) {
                    LockSupport.parkUntil(laterJob.startTime);
                } else {
                    laterJob = queue.poll();
                    executorService.execute(laterJob.task);
                    Job nextJob = new Job();
                    nextJob.setTask(laterJob.task);
                    nextJob.setDelay(laterJob.delay);
                    nextJob.setStartTime(System.currentTimeMillis() + laterJob.delay);
                    queue.offer(nextJob);
                }
            }

        });

        {
            System.out.println("tigger启动了");
            thread.start();
        }

        void wakeUp() {
            LockSupport.unpark(thread);
        }

    }

    @Data
    class Job implements Comparable<Job> {
        Runnable task;
        long startTime;
        long delay;

        @Override
        public int compareTo(@NotNull Job o) {
            return Long.compare(this.getStartTime(), o.getStartTime());
        }
    }
}
